| Conditions | 13 |
| Total Lines | 68 |
| Code Lines | 59 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like WebSocketClient.initSocket often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | import './types' |
||
| 51 | |||
| 52 | private initSocket(ws: wsc.Socket) { |
||
| 53 | const {queue, config} = this |
||
| 54 | this.open = true |
||
| 55 | this.ws = ws |
||
| 56 | this.onReadyQueue.forEach((fn: Function) => fn()) |
||
| 57 | this.onReadyQueue.splice(0) |
||
| 58 | const {id_key, data_key} = config.server |
||
| 59 | // Works also on previously opened sockets that do not fire 'open' event. |
||
| 60 | this.call('open', ws) |
||
| 61 | for(const msg_id in queue) ws.send(queue[msg_id].msg) |
||
| 62 | if(this.reconnect_timeout !== null) { |
||
| 63 | clearInterval(this.reconnect_timeout) |
||
| 64 | this.reconnect_timeout = null |
||
| 65 | } |
||
| 66 | if(config.ping) { |
||
| 67 | const ping_interval = setInterval(() => { |
||
| 68 | if(this.open) this.send(config.ping.content) |
||
| 69 | if(this.forcibly_closed) clearInterval(ping_interval) |
||
| 70 | }, config.ping.interval*1e3) |
||
| 71 | } |
||
| 72 | add_event(ws, 'close', async (...e) => { |
||
| 73 | this.log('close') |
||
| 74 | this.open = false |
||
| 75 | this.ws = null |
||
| 76 | this.onCloseQueue.forEach((fn: Function) => fn()) |
||
| 77 | this.onCloseQueue.splice(0) |
||
| 78 | this.call('close', ...e) |
||
| 79 | // Auto reconnect. |
||
| 80 | const reconnect = config.reconnect |
||
| 81 | if( |
||
| 82 | typeof reconnect === 'number' && |
||
| 83 | !isNaN(reconnect) && |
||
| 84 | !this.forcibly_closed |
||
| 85 | ) { |
||
| 86 | const reconnectFunc = async () => { |
||
| 87 | this.log('reconnect') |
||
| 88 | if(this.ws !== null) { |
||
| 89 | this.ws.close() |
||
| 90 | this.ws = null |
||
| 91 | } |
||
| 92 | // If some error occured, try again. |
||
| 93 | const status = await this.connect() |
||
| 94 | if(status !== null) |
||
| 95 | this.reconnect_timeout = setTimeout(reconnectFunc, reconnect * 1000) |
||
| 96 | } |
||
| 97 | // TODO: test normal close by server. Would it be infinite ? |
||
| 98 | reconnectFunc() |
||
| 99 | } |
||
| 100 | // reset the flag to reuse. |
||
| 101 | this.forcibly_closed = false |
||
| 102 | }) |
||
| 103 | add_event(ws, 'message', (e) => { |
||
| 104 | try { |
||
| 105 | const data = config.decode(e.data) |
||
| 106 | this.call('message', {...e, data}) |
||
| 107 | if(data[id_key]) { |
||
| 108 | const q = this.queue[data[id_key]] |
||
| 109 | if(q) { |
||
| 110 | // Debug, Log. |
||
| 111 | const time = q.sent_time ? (Date.now() - q.sent_time) : null |
||
| 112 | this.log('message', data[data_key], time) |
||
| 113 | // Play. |
||
| 114 | q.ff(data[data_key]) |
||
| 115 | } |
||
| 116 | } |
||
| 117 | } catch (err) { |
||
| 118 | console.error(err, `WSP: Decode error. Got: ${e.data}`) |
||
| 119 | } |
||
| 265 | export default WebSocketClient |